﻿using org.xisoft.game.GobangModule.Chess;
using org.xisoft.game.GobangModule.Chess.Algorithms;
using org.xisoft.game.utils;
using org.xisoft.game.utils.game;
using org.xisoft.game.utils.game.algorithms;
using System;
using System.Collections.Generic;
using System.Drawing;
using System.IO;
using System.Windows.Forms;

namespace org.xisoft.game.GobangModule
{
    public class GobangBroadControl : NormalBroadControl
    {
        private GobangBroad broad = new GobangBroad();
        private AiAlgorithm< GobangBroad> aiAlgorithm ;
        //private AiAlgorithm aiAlgorithm = new AiAlgorithm();
        public override string Name => "五子棋";

        public GobangBroadControl()
            :base(GobangBroad.MAXX, GobangBroad.MAXY)
        {
            //aiAlgorithm = new MulAlphaBetaAlgorithm<AiAlgorithm, GobangBroad>();
            //aiAlgorithm = new CachedAlgorithm<MulAlphaBetaAlgorithm<AiAlgorithm, GobangBroad>, GobangBroad>(mulAlphaBetaAlgorithm);
            aiAlgorithm = new AiAlgorithm();
        }



        protected override void DrawItems(Graphics g,Rectangle rect)
        {
            int maxIndexX=0;
            int maxIndexY = 0;
            int maxIndex = 0;

            for (int i = 0; i < MaxX; i++)
                for (int j = 0; j < MaxY; j++)
                {
                    ChessItem item = broad[i, j];
                    if (item == null) continue;
                    DrawItem(g, item.IsBlack ? blackItemBrush : writeItemBrush, i, j, item.DisplayName);
                    if(maxIndex<item.Index)
                    {
                        maxIndex = item.Index;
                        maxIndexX = i;
                        maxIndexY = j;
                    }
                }


            
            int left = maxIndexX * GridItemWidth + Rect.Left;
            int top = maxIndexY * GridItemHeight + Rect.Top;
            for(int i=2;i<10;i+=4)
            g.DrawEllipse(selectedItemPen, left - (ItemWidth+i) / 2, top - (ItemHeight+i) / 2, ItemWidth + i, ItemHeight+i);






            /*List<MoveAction> list = aiAlgorithm.GetAllCanMoves(broad);
            foreach (MoveAction action in list)
            {
                DrawItem(g, Brushes.AliceBlue, action.ToX, action.ToY, action.Score + "");
            }*/
        }

        private void DrawItem(Graphics g, Brush brush, int x, int y, String text)
        {
            int left = x * GridItemWidth + Rect.Left;
            int top = y * GridItemHeight + Rect.Top;

            g.FillEllipse(brush, left - ItemWidth / 2, top - ItemHeight / 2, ItemWidth, ItemHeight);

            SizeF sizef = g.MeasureString(text, Font);
           
            g.DrawString(text, Font, broadFontBrush, left - sizef.Width / 2+1, top - sizef.Height / 2+1);
        }




        AsyncTask<GobangBroad, MoveAction> task ;
        protected override void OnClick(int x, int y)
        {
            MoveAction moveAction = new MoveAction { ToX = x, ToY = y };
            aiAlgorithm.DoNext(broad,moveAction);
            Invalidate();
            ShowLoading();

            Boolean? winColor = aiAlgorithm.GetWinColor(broad);
            if (winColor.HasValue)
            {
                if (winColor.Value == false)
                    MessageBox.Show("你赢了");
                else
                    MessageBox.Show("你输了");
                HideLoading();
                return;
            }

            GobangBroad b = broad.Clone() as GobangBroad;

            if(task == null)
                task = new AsyncTask<GobangBroad, MoveAction>(ChessBoardControl, DoAfterMove);

            task.Start(aiAlgorithm.Search, b);

        }

        private void DoAfterMove(MoveAction moveAction)
        {
            if (moveAction == null)
                MessageBox.Show("你赢了");
            else
            {
                aiAlgorithm.DoNext(broad,moveAction);
                Boolean? winColor = aiAlgorithm.GetWinColor(broad);
                if (winColor.HasValue)
                {
                    if (winColor.Value == false)
                        MessageBox.Show("你赢了");
                    else
                        MessageBox.Show("你输了");
                }
            }

            Invalidate();
            HideLoading();
        }

        public override void Read(BinaryReader br)
        {
            broad.Read(br);
        }

        public override void Save(BinaryWriter bw)
        {
            broad.Save(bw);
        }



        public override void Undo()
        {
            broad.Undo();
            broad.Undo();
            Invalidate();
        }
    }
}
